"""

Preprocessor takes images from ALE and turns them into cropped, downscaled arrays of grayscale values.

"""

from PIL import Image
import numpy as np

class Preprocessor:

    grayscale_array = None
    desired_image_size = 84         # the size of the new image will be desired_image_size x desired_image_size

    def __init__(self):
        """
        Initialise preprocessor
        """
        self.grayscale_array = self.get_grayscale_array()

    def process(self, image_string):
        """
        Returns the cropped, downscaled, grayscale array representation of the image.
        @param image_string: a string that ALE outputs, corresponding to a 160x210 color image
        """
        arr = self.grayscale_array

        # Crop irrelevant lines from beginning and end
        cropped = image_string[160*33*2:160*193*2]

        # Split cropped image string into a list of hex codes
        hexs = [cropped[i*2:i*2+2] for i in range(len(cropped)/2)]

        # Map each element of the list to the corresponding gray value
        grays = np.asarray(map(lambda hex_val: arr[int(hex_val[1], 16) ,int(hex_val[0], 16)], hexs))

        # Turn the array into an image object and downscale
        img = Image.fromarray(grays.reshape((160, 160)))
        new_size = self.desired_image_size, self.desired_image_size
        img.thumbnail(new_size, Image.NEAREST)

        # Get pixel data again
        norm_pixels = np.asarray(img, dtype=np.float32) / 256.0
        return norm_pixels

    def get_grayscale_array(self):
        """
        Returns the (numpy) array that is used for mapping NTSC colors to grayscale values
        """
        
        my_array = np.array(
            [[0.000000000000000000e+00, 4.533333333333333570e+01, 5.066666666666666430e+01, 5.200000000000000000e+01, 4.533333333333333570e+01, 7.066666666666667140e+01, 6.400000000000000000e+01, 5.066666666666666430e+01, 4.533333333333333570e+01, 4.933333333333333570e+01, 4.533333333333333570e+01, 3.466666666666666430e+01, 2.000000000000000000e+01, 2.533333333333333215e+01, 3.066666666666666785e+01, 3.600000000000000000e+01],
            [6.400000000000000000e+01, 7.200000000000000000e+01, 7.333333333333332860e+01, 7.600000000000000000e+01, 7.333333333333332860e+01, 9.600000000000000000e+01, 9.066666666666667140e+01, 7.733333333333332860e+01, 7.200000000000000000e+01, 7.600000000000000000e+01, 7.466666666666667140e+01, 6.400000000000000000e+01, 5.200000000000000000e+01, 5.733333333333333570e+01, 6.133333333333333570e+01, 6.533333333333332860e+01],
            [1.080000000000000000e+02, 1.000000000000000000e+02, 9.466666666666667140e+01, 1.000000000000000000e+02, 9.866666666666667140e+01, 1.186666666666666714e+02, 1.146666666666666714e+02, 1.026666666666666714e+02, 9.866666666666667140e+01, 1.026666666666666714e+02, 1.013333333333333286e+02, 9.333333333333332860e+01, 8.400000000000000000e+01, 8.666666666666667140e+01, 8.933333333333332860e+01, 9.466666666666667140e+01],
            [1.440000000000000000e+02, 1.240000000000000000e+02, 1.173333333333333286e+02, 1.226666666666666714e+02, 1.226666666666666714e+02, 1.400000000000000000e+02, 1.373333333333333428e+02, 1.280000000000000000e+02, 1.213333333333333286e+02, 1.266666666666666714e+02, 1.280000000000000000e+02, 1.213333333333333286e+02, 1.133333333333333286e+02, 1.133333333333333286e+02, 1.160000000000000000e+02, 1.200000000000000000e+02],
            [1.760000000000000000e+02, 1.440000000000000000e+02, 1.346666666666666572e+02, 1.426666666666666572e+02, 1.440000000000000000e+02, 1.600000000000000000e+02, 1.586666666666666572e+02, 1.480000000000000000e+02, 1.426666666666666572e+02, 1.480000000000000000e+02, 1.506666666666666572e+02, 1.440000000000000000e+02, 1.373333333333333428e+02, 1.386666666666666572e+02, 1.413333333333333428e+02, 1.426666666666666572e+02],
            [2.000000000000000000e+02, 1.653333333333333428e+02, 1.520000000000000000e+02, 1.613333333333333428e+02, 1.653333333333333428e+02, 1.773333333333333428e+02, 1.773333333333333428e+02, 1.693333333333333428e+02, 1.626666666666666572e+02, 1.666666666666666572e+02, 1.720000000000000000e+02, 1.680000000000000000e+02, 1.626666666666666572e+02, 1.613333333333333428e+02, 1.640000000000000000e+02, 1.653333333333333428e+02],
            [2.200000000000000000e+02, 1.853333333333333428e+02, 1.680000000000000000e+02, 1.773333333333333428e+02, 1.853333333333333428e+02, 1.946666666666666572e+02, 1.960000000000000000e+02, 1.880000000000000000e+02, 1.813333333333333428e+02, 1.866666666666666572e+02, 1.933333333333333428e+02, 1.880000000000000000e+02, 1.853333333333333428e+02, 1.840000000000000000e+02, 1.840000000000000000e+02, 1.866666666666666572e+02],
            [2.360000000000000000e+02, 2.026666666666666572e+02, 1.853333333333333428e+02, 1.960000000000000000e+02, 2.040000000000000000e+02, 2.120000000000000000e+02, 2.133333333333333428e+02, 2.066666666666666572e+02, 2.000000000000000000e+02, 2.053333333333333428e+02, 2.133333333333333428e+02, 2.093333333333333428e+02, 2.066666666666666572e+02, 2.053333333333333428e+02, 2.053333333333333428e+02, 2.053333333333333428e+02]]
        )



        return my_array
